﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Media.Imaging;
using System.Windows;
using System.Windows.Media;

namespace WpfImageDuplicates
{
    public class FileImageViewModel : INotifyPropertyChanged
    {
        public event EventHandler<ObjectEventArgs<string>> DataLoaded;

        protected IFileImage _fileImage;
        protected FilterCollection _filterCollection;

        public FileImageViewModel(IFileImage fileImage)
        {
            this._fileImage = fileImage;
            this._fileImage.PropertyChanged += new PropertyChangedEventHandler(_fileImage_PropertyChanged);
        }

        public FileImageViewModel(IFileImage fileImage, FilterCollection filterCollection)
            : this(fileImage)
        {
            if (fileImage is OriginalAndTransformedBitmap)
            {
                OriginalAndTransformedBitmap transformed = fileImage as OriginalAndTransformedBitmap;
                transformed.FilterCollection = filterCollection;
            }
        }

        public void MarkDirty(bool clearThumb)
        {
            _fileImage.MarkDirty(clearThumb);
        }

        public void LoadBitmap()
        {
            _fileImage.DataLoaded += new EventHandler<ObjectEventArgs<string>>(_fileImage_DataLoaded);
            _fileImage.LoadBitmap();
        }

        public FilterCollection FilterCollection
        {
            get
            {
                return _filterCollection;
            }
            set
            {
                if (_filterCollection != value)
                {
                    _filterCollection = value;
                    OnPropertyChanged("FilterCollection");
                }
            }
        }

        public bool ViewerIsTopmost
        {
            get
            {
                return Settings.Values.ViewerIsTopmost;
            }
            set
            {
                if (Settings.Values.ViewerIsTopmost != value)
                {
                    Settings.Values.ViewerIsTopmost = value;
                    OnPropertyChanged("ViewerIsTopmost");
                }
            }
        }

        void _fileImage_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnPropertyChanged(e.PropertyName);
        }

        void _fileImage_DataLoaded(object sender, ObjectEventArgs<string> e)
        {
            _fileImage.DataLoaded -= _fileImage_DataLoaded;

            if (DataLoaded != null)
                DataLoaded(this, e);
        }

        public IFileImage FileImage
        {
            get
            {
                return _fileImage;
            }
        }

        public override bool Equals(object obj)
        {
            FileImageViewModel vm = obj as FileImageViewModel;
            if (vm != null)
            {
                return vm._fileImage.Equals(this._fileImage);
            }
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public string FileNameOnly
        {
            get
            {
                return System.IO.Path.GetFileName(_fileImage.FileName);
            }
        }

        public string FileName
        {
            get
            {
                return _fileImage.FileName;
            }
            set
            {
                if (_fileImage.FileName != value)
                {
                    _fileImage.FileName = value;
                    OnPropertyChanged("FileName");
                }
            }
        }

        public Bitmap Bitmap
        {
            get
            {
                return _fileImage.Bitmap;
            }
            set
            {
                if (_fileImage.BitmapCached != value)
                {
                    _fileImage.Bitmap = value;
                    OnPropertyChanged("Bitmap");
                    OnPropertyChanged("ImageSource");                    
                }
            }
        }

        public BitmapImage BitmapImage
        {
            get { return _fileImage.BitmapImage; }            
        }

        public bool BitmapLoaded
        {
            get { return _fileImage.BitmapLoaded; }
        }

        public bool BitmapImageLoaded
        {
            get { return _fileImage.BitmapImageLoaded; }
        }

        public void FreeBitmap(bool releaseThumb)
        {
            _fileImage.FreeBitmap(releaseThumb);
        }

        public void FreeBitmapImage(bool releaseThumb)
        {
            _fileImage.FreeBitmapImage(releaseThumb);
        }

        public void ClearThumbnail()
        {
            Thumbnail = null;
        }

        public Bitmap Thumbnail
        {
            get
            {                
                return _fileImage.Thumbnail;
            }
            set
            {
                if (_fileImage.ThumbnailCached != value)
                {
                    _fileImage.Thumbnail = value;                    
                    OnPropertyChanged("Thumbnail");
                }
            }

        }

        public int FileSize
        {
            get
            {
                return _fileImage.FileSize;
            }
        }

        public void Delete()
        {
            _fileImage.Delete();
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public ImageSource ImageSource
        {
            get
            {
                return _fileImage.ImageSource;
            }
        }
        
        public double OriginalHeight
        {
            get
            {
                if (_fileImage.BitmapImage == null)
                    return double.NaN;

                return _fileImage.BitmapImage.Height;
            }
        }

        public double OriginalWidth
        {
            get
            {
                if (_fileImage.BitmapImage == null)
                    return double.NaN;

                return _fileImage.BitmapImage.Width;
            }
        }

        public void ClearFilteredImage()
        {
            _fileImage.MarkDirty(false);            
        }

        public bool SuspendUnload
        {
            get
            {
                return _fileImage.SuspendUnload;
            }
            set
            {
                _fileImage.SuspendUnload = value;
            }
        }
    }
}
